const del = require('del');
const utils = require('./utils');
const webfontsGenerator = require('@vusion/webfonts-generator');
const util = require('util');
const path = require('path');
const fs = require('fs');
const uglifycss = require('uglifycss');
const writeFile = util.promisify(fs.writeFile);
const chalk = require('chalk');

const mimeTypes = {
    'eot': 'application/vnd.ms-fontobject',
    'svg': 'image/svg+xml',
    'ttf': 'application/x-font-ttf',
    'woff': 'application/font-woff',
    'woff2': 'font/woff2'
};

class KissFontPlugin {
    constructor(options) {
        if (options) {
            utils.setPluginConfig(options);
        }
    }

    async generate(config) {
        try {
            const {
                fontName,
                cssFileName,
                classPrefix,
                baseSelector,
                dest,
                types,
                embed,
                isWriteFiles,
                isWriteCss,
                isUglifyCss
            } = config;
            const result = await util.promisify(webfontsGenerator)({
                ...config,
                templateOptions: {
                    classPrefix,
                    baseSelector
                },
                writeFiles: false
            });

            if (isWriteFiles || isWriteCss) {
                await utils.mkdir(dest);
            }

            const options = {};
            const time = Date.now();
            await Promise.all(types.map(async (type) => {
                const fileName = fontName + '-' + time + '.' + type; //生成字体文件的名称
                if (embed) {
                    options[type] = 'data:' + mimeTypes[type] + ';charset=utf-8;base64,' + (Buffer.from(result[type]).toString('base64'));
                } else {
                    options[type] = fileName;
                }

                if (isWriteFiles) {
                    await writeFile(path.join(dest, fileName), result[type]);
                }
            }));
            const data = result.generateCss(options);
            const css = isUglifyCss ? uglifycss.processString(data) : data;
            if (isWriteCss) {
                await writeFile(path.join(dest, cssFileName + '.css'), css);
            }
            return css;
        } catch (e) {
            console.error(e);
        }
    }

    apply(compiler) {
        const isDev = utils.isDevelop();
        if (isDev) {
            compiler.hooks.beforeCompile.tap('KissFontPlugin', () => {
                utils.clearRequireConfigCache();
            });
        } else {
            //生产环境
            const tmpDir = utils.getTmpDir();
            console.log();
            console.log(chalk.bold(`删除目录【${chalk.green(tmpDir)}】`));
            del.sync(tmpDir, { force: true });
        }

        const rootContext = compiler.options.context;
        let entryArr = compiler.options.entry.app;
        if (!Array.isArray(entryArr)) {
            entryArr = [entryArr];
        }
        //其实vue项目直接用process.env.VUE_CLI_ENTRY_FILES就可以，不过为了也支持webpack及未来其它的框架，就存一下吧
        utils.saveTempEntry(entryArr.map(p => path.resolve(rootContext, p)));

        compiler.hooks.compilation.tap('KissFontPlugin', (compilation) => {
            compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync('html-webpack-plugin-before-html-processing', async (data, callback) => {
                const config = utils.getConfig();
                if (!isDev) {
                    const cssPath = `${config.webfontDir}/${config.cssFileName}.css?${Date.now()}`;
                    data.assets.css.push(cssPath);
                }
                //生成css与字体
                const svgPath = utils.getSvgPath();
                const files = await utils.getFilesByDir(svgPath);
                if (files && files.length > 0 && process.env.__KISS_FONT_FILES__ !== JSON.stringify(files)) {
                    process.env.__KISS_FONT_FILES__ = JSON.stringify(files);
                    console.log();
                    const svgTimeTag = chalk.green('svg生成字体耗时');
                    console.time(svgTimeTag);
                    // const dest = isDev ? path.resolve(utils.getTmpDir(), config.webfontDir) : path.resolve(compiler.options.output.path, config.webfontDir);
                    // 开发时css生成路径与js-loader注入的有关，要修改的话得一起修改
                    const dest = isDev ? utils.getTempCssDir() : path.resolve(compiler.options.output.path, config.webfontDir);
                    await this.generate({
                        ...config,
                        files,
                        dest,
                        embed: isDev,
                        isWriteFiles: !isDev,
                        isWriteCss: true,
                        isUglifyCss: !isDev
                    });
                    console.timeEnd(svgTimeTag);
                    // if (isDev) {
                    //     // const dir = path.resolve(compiler.options.output.path, config.webfontDir);
                    //     const dir = path.resolve('node_modules', 'kiss-font-plugin');
                    //     compiler.outputFileSystem.mkdirpSync(dir);
                    //     compiler.outputFileSystem.writeFileSync(path.join(dir, config.fontName + '.css'), css);
                    // }
                }
                callback(null, data);
            });
        });

    }
}
// 导出插件 
module.exports = KissFontPlugin;
